package com.ruoyi.access.service.impl;

import com.ruoyi.access.domain.AccessControlRule;
import com.ruoyi.access.domain.UserAccessRequest;
import com.ruoyi.access.domain.AccessDecisionLog;
import com.ruoyi.access.mapper.AccessControlMapper;
import com.ruoyi.access.service.IAccessControlService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class AccessControlServiceImpl implements IAccessControlService {

    @Resource
    private AccessControlMapper mapper;

    @Override
    public Long submitRequest(Long userId, String resourceType, Long resourceId, String action) {
        UserAccessRequest req = new UserAccessRequest();
        req.setUserId(userId);
        req.setResourceType(resourceType);
        req.setResourceId(resourceId);
        req.setAction(action);
        req.setStatus("pending");
        mapper.insertUserRequest(req);
        return req.getRequestId();
    }

    @Override
    public String evaluateRequest(Long requestId, String resourceType, Long resourceId, String action) {
        AccessControlRule rule = mapper.selectRule(resourceType, resourceId, action);
        String decision = (rule != null && "allow".equalsIgnoreCase(rule.getEffect())) ? "allow" : "deny";

        // 更新请求状态
        mapper.updateUserRequestStatus(requestId, decision.equals("allow") ? "approved" : "denied");

        // 记录日志
        AccessDecisionLog log = new AccessDecisionLog();
        log.setRequestId(requestId);
        log.setDecision(decision);
        log.setReason(rule != null ? "Matched rule " + rule.getRuleId() : "No matching rule");
        mapper.insertDecisionLog(log);

        return decision;
    }

    @Override
    public boolean approveAccessRequest(Long requestId) {
        // 这里更新数据库中 request 的状态
        int rows = mapper.updateUserRequestStatus(requestId, "APPROVED");
        return rows > 0;
    }

    @Override
    public boolean revokePermission(Long permissionId) {
        int rows = mapper.revokePermission(permissionId);
        return rows > 0;
    }
}
